﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace laohan.Common.USB.Cryptology
{
	public class XteaCryptoProvider
	{
		private byte[] intToByte(uint val)
		{
			byte[] array = new byte[4];
			array[3] = Convert.ToByte(val & 0xFFu);
			array[2] = Convert.ToByte((val & 0xFF00) >> 8);
			array[1] = Convert.ToByte((val & 0xFF0000) >> 16);
			array[0] = Convert.ToByte((val & 0xFF000000u) >> 24);
			return array;
		}

		private uint ReverseBytes(uint val)
		{
			return ((val & 0xFF) << 24) | ((val & 0xFF00) << 8) | ((val & 0xFF0000) >> 8) | ((val & 0xFF000000u) >> 24);
		}

		public byte[] XteaEncrypt(byte[] buf, byte[] teaKey)
		{
			int num = buf.Length;
			int num2 = num / 4;
			uint[] array = new uint[num2];
			uint[] array2 = new uint[num2];
			for (int i = 0; i < num2; i++)
			{
				array[i] = (uint)((buf[i * 4 + 3] << 24) | (buf[i * 4 + 2] << 16) | (buf[i * 4 + 1] << 8) | buf[i * 4]);
			}
			uint[] array3 = new uint[4];
			for (int i = 0; i < 4; i++)
			{
				array3[i] = (uint)((teaKey[i * 4 + 3] << 24) | (teaKey[i * 4 + 2] << 16) | (teaKey[i * 4 + 1] << 8) | teaKey[i * 4]);
			}
			uint num3 = array[num2 - 1];
			uint num4 = array[0];
			uint num5 = 0u;
			int num6 = (byte)(1 + 52 / num2);
			while (num6-- > 0)
			{
				num5 += 2654435769u;
				uint num7 = (num5 >> 2) & 3u;
				int j;
				for (j = 0; j < num2 - 1; j++)
				{
					num4 = array[j + 1];
					num3 = (array[j] += (((num3 >> 5) ^ (num4 << 2)) + ((num4 >> 3) ^ (num3 << 4))) ^ ((num5 ^ num4) + (array3[(j & 3) ^ num7] ^ num3)));
				}
				num4 = array[0];
				num3 = (array[num2 - 1] += (((num3 >> 5) ^ (num4 << 2)) + ((num4 >> 3) ^ (num3 << 4))) ^ ((num5 ^ num4) + (array3[(j & 3) ^ num7] ^ num3)));
			}
			for (int i = 0; i < num2; i++)
			{
				array2[i] = ReverseBytes(array[i]);
			}
			byte[] array4 = new byte[num];
			ushort num8 = 0;
			for (int i = 0; i < num2; i++)
			{
				byte[] array5 = new byte[4];
				array5 = intToByte(array2[i]);
				for (byte b = 0; b < 4; b = (byte)(b + 1))
				{
					array4[num8] = array5[b];
					num8 = (ushort)(num8 + 1);
				}
			}
			return array4;
		}

		public byte[] XteaDecrpyt(byte[] buf, byte[] teaKey)
		{
			int num = buf.Length;
			int num2 = num / 4;
			uint[] array = new uint[num2];
			uint[] array2 = new uint[num2];
			for (byte b = 0; b < num2; b = (byte)(b + 1))
			{
				array[b] = (uint)((buf[b * 4 + 3] << 24) | (buf[b * 4 + 2] << 16) | (buf[b * 4 + 1] << 8) | buf[b * 4]);
			}
			uint[] array3 = new uint[4];
			for (byte b = 0; b < 4; b = (byte)(b + 1))
			{
				array3[b] = (uint)((teaKey[b * 4 + 3] << 24) | (teaKey[b * 4 + 2] << 16) | (teaKey[b * 4 + 1] << 8) | teaKey[b * 4]);
			}
			uint num3 = array[num2 - 1];
			uint num4 = array[0];
			uint num5 = 0u;
			for (num5 = (uint)((byte)(1 + 52 / num2) * -1640531527); num5 != 0; num5 -= 2654435769u)
			{
				uint num6 = (num5 >> 2) & 3u;
				byte b2;
				for (b2 = (byte)(num2 - 1); b2 > 0; b2 = (byte)(b2 - 1))
				{
					num3 = array[b2 - 1];
					num4 = (array[b2] -= (((num3 >> 5) ^ (num4 << 2)) + ((num4 >> 3) ^ (num3 << 4))) ^ ((num5 ^ num4) + (array3[(b2 & 3) ^ num6] ^ num3)));
				}
				num3 = array[num2 - 1];
				num4 = (array[0] -= (((num3 >> 5) ^ (num4 << 2)) + ((num4 >> 3) ^ (num3 << 4))) ^ ((num5 ^ num4) + (array3[(b2 & 3) ^ num6] ^ num3)));
			}
			for (byte b = 0; b < num2; b = (byte)(b + 1))
			{
				array2[b] = ReverseBytes(array[b]);
			}
			byte[] array4 = new byte[num];
			ushort num7 = 0;
			for (byte b = 0; b < num2; b = (byte)(b + 1))
			{
				byte[] array5 = new byte[4];
				array5 = intToByte(array2[b]);
				for (byte b3 = 0; b3 < 4; b3 = (byte)(b3 + 1))
				{
					array4[num7] = array5[b3];
					num7 = (ushort)(num7 + 1);
				}
			}
			return array4;
		}
	}
}
